package com.yswy.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author zhuoxiaoya
 * @Description 云通讯接入获取验证码工具类
 * @Date 15:51 2019/8/9
 * @Param
 * @return
 **/
public class TemplateSMSUtil {


    //生产环境的baseURL
    private static String BASEURL = "https://app.cloopen.com:8883";

    //开发者主账户ACCOUNT SID（登陆官网在管理控制台获取）
    //8a48b551544cd73f015474c5cbdd221b
    private static String ACCOUNTSID = "8a48b551544cd73f015474c5cbdd221b";
    //47b04cd1476847d59faaefd34912a5d7
    private static String AUTHTOKEN ="47b04cd1476847d59faaefd34912a5d7";

    //1.使用MD5加密（账户Id + 账户授权令牌 + 时间戳）。其中账户Id和账户授权令牌根据url的验证级别对应主账户。
    //时间戳是当前系统时间，格式"yyyyMMddHHmmss"。时间戳有效时间为24小时，如：20140416142030
    //2.SigParameter参数需要大写，如不能写成sig=abcdefg而应该写成sig=ABCDEFG
    private static String SIGPARAMETER = "";

    private static String urlHead = "/2013-12-26/Accounts/";
    private static String urlTail = "/SMS/TemplateSMS?sig=";
    private static String[] datas;

    //设置请求
    public static Map<String,Object> sendPsot(String phone,String appId,String templateId){
        Map<String,Object> maps = new HashMap<>();
        RestTemplate restTemplate = new RestTemplate();
        Date date = new Date();
        String verification = getRandomCode();
        String time = "5分钟";
        datas = new String[]{verification,time};

        //获取请求的路径
        String url = getPostUrl(date);

        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.setContentLength(256);
        headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
        headers.set("Authorization",getAuthorizationByBase64(date));

        Map<String, Object> map= new HashMap<>();
        map.put("to", phone);
        map.put("appId", appId);
        map.put("templateId", templateId);
        map.put("datas",datas);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers);
        ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class);

        //处理响应
        String body = response.getBody();
        JSONObject jsonObject = JSONObject.parseObject(body);
        maps.put("code",jsonObject.getString("statusCode"));

        if(jsonObject.getString("statusCode").equals("000000")){
            JSONObject model = JSONObject.parseObject(jsonObject.getString("templateSMS"));
            maps.put("smsMessageSid",model.getString("smsMessageSid"));
            OrderCode orderCode = new OrderCode();
            orderCode.setCode(verification);
            orderCode.setSmsMessageSid(model.getString("smsMessageSid"));
            maps.put("orderCode",orderCode);

            //2020年6月11日 新增短信验证码
            maps.put("phoneCode",verification);
        }else{
            maps.put("errorMsg",jsonObject.getString("statusMsg"));
        }
        return maps;
    }


//    public static void main(String[] args) {
////        Map<String,Object> map = sendPsot("18080455214",
////                "8a216da86f696570016f69f60ba40068", "1021413");
////
////
////        System.out.println(map);
//        Map<String,Object>  map = sendPsot("18080455214",
//                "8a216da8719c20ad0171bebf3e1511c1", "590239" );
//
//
//        System.out.println(map);
//    }


    //参数md5加密32位大写
    public final static String MD5By32(String s) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            try {
                byte[] btInput = s.getBytes();
                // 获得MD5摘要算法的 MessageDigest 对象
                MessageDigest mdInst = MessageDigest.getInstance("MD5");
                // 使用指定的字节更新摘要
                mdInst.update(btInput);
                // 获得密文
                byte[] md = mdInst.digest();
                // 把密文转换成十六进制的字符串形式
                int j = md.length;
                char str[] = new char[j * 2];
                int k = 0;
                for (int i = 0; i < j; i++) {
                    byte byte0 = md[i];
                    str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                    str[k++] = hexDigits[byte0 & 0xf];
                }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //参数base64加密Authorization
    //使用Base64编码（账户Id + 冒号 + 时间戳）其中账户Id根据url的验证级别对应主账户
    //冒号为英文冒号
    //时间戳是当前系统时间，格式"yyyyMMddHHmmss"，需与SigParameter中时间戳相同
    public static String getAuthorizationByBase64(Date date){
        StringBuffer authorization = new StringBuffer();
        authorization.append(ACCOUNTSID);
        authorization.append(":");
        authorization.append(getTimeStamp(date));
        String content = authorization.toString();
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(content.getBytes());
    }



    //参数md5加密
    public static String encodeByMd5(String string) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        // 确定计算方法
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        Base64.Encoder base64Encoder = Base64.getEncoder();
        // 加密字符串
        return base64Encoder.encodeToString(md5.digest(string.getBytes("utf-8")));
    }

    //获取当前系统时间戳格式为yyyyMMddHHmmss
    public static String getTimeStamp(Date date){
        SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
        return sim.format(date);
    }

    //设置 SIGPARAMETER 的加密明文
    public static String getSigParamEter(Date date){
        StringBuffer sb = new StringBuffer();
        sb.append(ACCOUNTSID);
        sb.append(AUTHTOKEN);
        sb.append(getTimeStamp(date));
        String param = sb.toString();
        return MD5By32(param);
    }

    //获取验证码接口URL地址
    public static String getPostUrl(Date date){
        StringBuffer url = new StringBuffer();
        url.append(BASEURL);
        url.append(urlHead);
        url.append(ACCOUNTSID);
        url.append(urlTail);
        url.append(getSigParamEter(date));
        String rusultUrl = url.toString();
        return rusultUrl;
    }

    //6位验证码随机数
    public static String getRandomCode(){
        Random random = new Random();
        String result="";
        for (int i=0;i<6;i++) {
            result+=random.nextInt(10);
        }
        return result;
    }

}